gooddata-edge 0.6.27.edge

Sign up to get free protection for your applications and to get access to all the features.
Files changed (364) hide show
  1. checksums.yaml +7 -0
  2. data/.document +5 -0
  3. data/.gitignore +36 -0
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +89 -0
  6. data/.yardopts +22 -0
  7. data/CHANGELOG.md +196 -0
  8. data/CLI.md +439 -0
  9. data/DEPENDENCIES.md +817 -0
  10. data/Gemfile +4 -0
  11. data/Guardfile +5 -0
  12. data/LICENSE +22 -0
  13. data/LICENSE.rb +5 -0
  14. data/README.md +75 -0
  15. data/Rakefile +179 -0
  16. data/TODO.md +32 -0
  17. data/authors.sh +4 -0
  18. data/bin/gooddata +7 -0
  19. data/dependency_decisions.yml +104 -0
  20. data/gooddata +9 -0
  21. data/gooddata.gemspec +63 -0
  22. data/lib/gooddata.rb +31 -0
  23. data/lib/gooddata/app/app.rb +16 -0
  24. data/lib/gooddata/bricks/base_downloader.rb +86 -0
  25. data/lib/gooddata/bricks/brick.rb +38 -0
  26. data/lib/gooddata/bricks/bricks.rb +15 -0
  27. data/lib/gooddata/bricks/middleware/aws_middleware.rb +29 -0
  28. data/lib/gooddata/bricks/middleware/base_middleware.rb +56 -0
  29. data/lib/gooddata/bricks/middleware/bench_middleware.rb +24 -0
  30. data/lib/gooddata/bricks/middleware/bulk_salesforce_middleware.rb +37 -0
  31. data/lib/gooddata/bricks/middleware/decode_params_middleware.rb +20 -0
  32. data/lib/gooddata/bricks/middleware/fs_download_middleware.rb +48 -0
  33. data/lib/gooddata/bricks/middleware/fs_upload_middleware.rb +36 -0
  34. data/lib/gooddata/bricks/middleware/gooddata_middleware.rb +39 -0
  35. data/lib/gooddata/bricks/middleware/logger_middleware.rb +29 -0
  36. data/lib/gooddata/bricks/middleware/middleware.rb +12 -0
  37. data/lib/gooddata/bricks/middleware/restforce_middleware.rb +61 -0
  38. data/lib/gooddata/bricks/middleware/stdout_middleware.rb +23 -0
  39. data/lib/gooddata/bricks/middleware/twitter_middleware.rb +29 -0
  40. data/lib/gooddata/bricks/middleware/undot_params_middleware.rb +37 -0
  41. data/lib/gooddata/bricks/pipeline.rb +32 -0
  42. data/lib/gooddata/bricks/utils.rb +18 -0
  43. data/lib/gooddata/cli/cli.rb +27 -0
  44. data/lib/gooddata/cli/commands/auth_cmd.rb +29 -0
  45. data/lib/gooddata/cli/commands/domain_cmd.rb +28 -0
  46. data/lib/gooddata/cli/commands/project_cmd.rb +45 -0
  47. data/lib/gooddata/cli/hooks.rb +57 -0
  48. data/lib/gooddata/cli/shared.rb +61 -0
  49. data/lib/gooddata/cli/terminal.rb +20 -0
  50. data/lib/gooddata/client.rb +67 -0
  51. data/lib/gooddata/commands/api.rb +64 -0
  52. data/lib/gooddata/commands/auth.rb +107 -0
  53. data/lib/gooddata/commands/base.rb +12 -0
  54. data/lib/gooddata/commands/commands.rb +12 -0
  55. data/lib/gooddata/commands/datasets.rb +148 -0
  56. data/lib/gooddata/commands/datawarehouse.rb +20 -0
  57. data/lib/gooddata/commands/domain.rb +40 -0
  58. data/lib/gooddata/commands/process.rb +67 -0
  59. data/lib/gooddata/commands/project.rb +175 -0
  60. data/lib/gooddata/commands/projects.rb +20 -0
  61. data/lib/gooddata/commands/role.rb +36 -0
  62. data/lib/gooddata/commands/runners.rb +47 -0
  63. data/lib/gooddata/commands/scaffold.rb +69 -0
  64. data/lib/gooddata/commands/user.rb +39 -0
  65. data/lib/gooddata/connection.rb +127 -0
  66. data/lib/gooddata/core/core.rb +12 -0
  67. data/lib/gooddata/core/logging.rb +105 -0
  68. data/lib/gooddata/core/nil_logger.rb +23 -0
  69. data/lib/gooddata/core/project.rb +74 -0
  70. data/lib/gooddata/core/rest.rb +149 -0
  71. data/lib/gooddata/core/user.rb +20 -0
  72. data/lib/gooddata/data/data.rb +12 -0
  73. data/lib/gooddata/data/guesser.rb +122 -0
  74. data/lib/gooddata/exceptions/attr_element_not_found.rb +16 -0
  75. data/lib/gooddata/exceptions/command_failed.rb +11 -0
  76. data/lib/gooddata/exceptions/exceptions.rb +12 -0
  77. data/lib/gooddata/exceptions/execution_limit_exceeded.rb +13 -0
  78. data/lib/gooddata/exceptions/filter_maqlization.rb +16 -0
  79. data/lib/gooddata/exceptions/malformed_user.rb +15 -0
  80. data/lib/gooddata/exceptions/no_project_error.rb +15 -0
  81. data/lib/gooddata/exceptions/object_migration.rb +32 -0
  82. data/lib/gooddata/exceptions/project_not_found.rb +13 -0
  83. data/lib/gooddata/exceptions/segment_not_empty.rb +18 -0
  84. data/lib/gooddata/exceptions/uncomputable_report.rb +13 -0
  85. data/lib/gooddata/exceptions/user_in_different_domain.rb +15 -0
  86. data/lib/gooddata/exceptions/validation_error.rb +16 -0
  87. data/lib/gooddata/extensions/big_decimal.rb +17 -0
  88. data/lib/gooddata/extensions/enumerable.rb +39 -0
  89. data/lib/gooddata/extensions/extensions.rb +10 -0
  90. data/lib/gooddata/extensions/false.rb +15 -0
  91. data/lib/gooddata/extensions/hash.rb +38 -0
  92. data/lib/gooddata/extensions/nil.rb +15 -0
  93. data/lib/gooddata/extensions/numeric.rb +15 -0
  94. data/lib/gooddata/extensions/object.rb +27 -0
  95. data/lib/gooddata/extensions/symbol.rb +15 -0
  96. data/lib/gooddata/extensions/true.rb +15 -0
  97. data/lib/gooddata/extract.rb +21 -0
  98. data/lib/gooddata/goodzilla/goodzilla.rb +159 -0
  99. data/lib/gooddata/helpers/auth_helpers.rb +75 -0
  100. data/lib/gooddata/helpers/csv_helper.rb +61 -0
  101. data/lib/gooddata/helpers/data_helper.rb +116 -0
  102. data/lib/gooddata/helpers/global_helpers.rb +331 -0
  103. data/lib/gooddata/helpers/global_helpers_params.rb +172 -0
  104. data/lib/gooddata/helpers/helpers.rb +10 -0
  105. data/lib/gooddata/mixins/author.rb +26 -0
  106. data/lib/gooddata/mixins/content_getter.rb +15 -0
  107. data/lib/gooddata/mixins/content_property_reader.rb +17 -0
  108. data/lib/gooddata/mixins/content_property_writer.rb +17 -0
  109. data/lib/gooddata/mixins/contributor.rb +20 -0
  110. data/lib/gooddata/mixins/data_getter.rb +15 -0
  111. data/lib/gooddata/mixins/data_property_reader.rb +19 -0
  112. data/lib/gooddata/mixins/data_property_writer.rb +19 -0
  113. data/lib/gooddata/mixins/inspector.rb +53 -0
  114. data/lib/gooddata/mixins/is_attribute.rb +17 -0
  115. data/lib/gooddata/mixins/is_dimension.rb +17 -0
  116. data/lib/gooddata/mixins/is_fact.rb +17 -0
  117. data/lib/gooddata/mixins/is_label.rb +19 -0
  118. data/lib/gooddata/mixins/links.rb +15 -0
  119. data/lib/gooddata/mixins/md_finders.rb +77 -0
  120. data/lib/gooddata/mixins/md_grantees.rb +42 -0
  121. data/lib/gooddata/mixins/md_id_to_uri.rb +34 -0
  122. data/lib/gooddata/mixins/md_json.rb +15 -0
  123. data/lib/gooddata/mixins/md_lock.rb +87 -0
  124. data/lib/gooddata/mixins/md_object_id.rb +15 -0
  125. data/lib/gooddata/mixins/md_object_indexer.rb +64 -0
  126. data/lib/gooddata/mixins/md_object_query.rb +128 -0
  127. data/lib/gooddata/mixins/md_relations.rb +43 -0
  128. data/lib/gooddata/mixins/meta_getter.rb +17 -0
  129. data/lib/gooddata/mixins/meta_property_reader.rb +19 -0
  130. data/lib/gooddata/mixins/meta_property_writer.rb +19 -0
  131. data/lib/gooddata/mixins/mixins.rb +19 -0
  132. data/lib/gooddata/mixins/not_attribute.rb +17 -0
  133. data/lib/gooddata/mixins/not_exportable.rb +15 -0
  134. data/lib/gooddata/mixins/not_fact.rb +17 -0
  135. data/lib/gooddata/mixins/not_group.rb +17 -0
  136. data/lib/gooddata/mixins/not_label.rb +19 -0
  137. data/lib/gooddata/mixins/not_metric.rb +19 -0
  138. data/lib/gooddata/mixins/obj_id.rb +15 -0
  139. data/lib/gooddata/mixins/rest_getters.rb +17 -0
  140. data/lib/gooddata/mixins/rest_resource.rb +47 -0
  141. data/lib/gooddata/mixins/root_key_getter.rb +15 -0
  142. data/lib/gooddata/mixins/root_key_setter.rb +15 -0
  143. data/lib/gooddata/mixins/timestamps.rb +19 -0
  144. data/lib/gooddata/mixins/to_json.rb +11 -0
  145. data/lib/gooddata/mixins/uri_getter.rb +9 -0
  146. data/lib/gooddata/models/blueprint/anchor_field.rb +64 -0
  147. data/lib/gooddata/models/blueprint/attribute_field.rb +29 -0
  148. data/lib/gooddata/models/blueprint/blueprint.rb +11 -0
  149. data/lib/gooddata/models/blueprint/blueprint_field.rb +70 -0
  150. data/lib/gooddata/models/blueprint/dashboard_builder.rb +30 -0
  151. data/lib/gooddata/models/blueprint/dataset_blueprint.rb +449 -0
  152. data/lib/gooddata/models/blueprint/date_dimension.rb +14 -0
  153. data/lib/gooddata/models/blueprint/fact_field.rb +20 -0
  154. data/lib/gooddata/models/blueprint/label_field.rb +43 -0
  155. data/lib/gooddata/models/blueprint/project_blueprint.rb +746 -0
  156. data/lib/gooddata/models/blueprint/project_builder.rb +83 -0
  157. data/lib/gooddata/models/blueprint/reference_field.rb +43 -0
  158. data/lib/gooddata/models/blueprint/schema_blueprint.rb +160 -0
  159. data/lib/gooddata/models/blueprint/schema_builder.rb +89 -0
  160. data/lib/gooddata/models/blueprint/to_manifest.rb +181 -0
  161. data/lib/gooddata/models/blueprint/to_wire.rb +154 -0
  162. data/lib/gooddata/models/client.rb +182 -0
  163. data/lib/gooddata/models/client_synchronization_result.rb +31 -0
  164. data/lib/gooddata/models/client_synchronization_result_details.rb +41 -0
  165. data/lib/gooddata/models/datawarehouse.rb +92 -0
  166. data/lib/gooddata/models/domain.rb +479 -0
  167. data/lib/gooddata/models/execution.rb +115 -0
  168. data/lib/gooddata/models/execution_detail.rb +81 -0
  169. data/lib/gooddata/models/from_wire.rb +160 -0
  170. data/lib/gooddata/models/invitation.rb +75 -0
  171. data/lib/gooddata/models/links.rb +50 -0
  172. data/lib/gooddata/models/membership.rb +441 -0
  173. data/lib/gooddata/models/metadata.rb +272 -0
  174. data/lib/gooddata/models/metadata/attribute.rb +134 -0
  175. data/lib/gooddata/models/metadata/dashboard.rb +108 -0
  176. data/lib/gooddata/models/metadata/dashboard/dashboard_item.rb +76 -0
  177. data/lib/gooddata/models/metadata/dashboard/filter_apply_item.rb +37 -0
  178. data/lib/gooddata/models/metadata/dashboard/filter_item.rb +64 -0
  179. data/lib/gooddata/models/metadata/dashboard/geo_chart_item.rb +56 -0
  180. data/lib/gooddata/models/metadata/dashboard/headline_item.rb +56 -0
  181. data/lib/gooddata/models/metadata/dashboard/iframe_item.rb +46 -0
  182. data/lib/gooddata/models/metadata/dashboard/report_item.rb +92 -0
  183. data/lib/gooddata/models/metadata/dashboard/text_item.rb +55 -0
  184. data/lib/gooddata/models/metadata/dashboard_tab.rb +141 -0
  185. data/lib/gooddata/models/metadata/dataset.rb +64 -0
  186. data/lib/gooddata/models/metadata/dimension.rb +54 -0
  187. data/lib/gooddata/models/metadata/fact.rb +44 -0
  188. data/lib/gooddata/models/metadata/label.rb +128 -0
  189. data/lib/gooddata/models/metadata/metadata.rb +12 -0
  190. data/lib/gooddata/models/metadata/metric.rb +198 -0
  191. data/lib/gooddata/models/metadata/report.rb +247 -0
  192. data/lib/gooddata/models/metadata/report_definition.rb +264 -0
  193. data/lib/gooddata/models/metadata/scheduled_mail.rb +274 -0
  194. data/lib/gooddata/models/metadata/scheduled_mail/dashboard_attachment.rb +62 -0
  195. data/lib/gooddata/models/metadata/scheduled_mail/report_attachment.rb +64 -0
  196. data/lib/gooddata/models/metadata/variable.rb +91 -0
  197. data/lib/gooddata/models/model.rb +282 -0
  198. data/lib/gooddata/models/models.rb +12 -0
  199. data/lib/gooddata/models/module_constants.rb +31 -0
  200. data/lib/gooddata/models/process.rb +316 -0
  201. data/lib/gooddata/models/profile.rb +426 -0
  202. data/lib/gooddata/models/project.rb +1514 -0
  203. data/lib/gooddata/models/project_creator.rb +126 -0
  204. data/lib/gooddata/models/project_metadata.rb +67 -0
  205. data/lib/gooddata/models/project_role.rb +79 -0
  206. data/lib/gooddata/models/report_data_result.rb +266 -0
  207. data/lib/gooddata/models/schedule.rb +518 -0
  208. data/lib/gooddata/models/segment.rb +201 -0
  209. data/lib/gooddata/models/tab_builder.rb +27 -0
  210. data/lib/gooddata/models/user_filters/mandatory_user_filter.rb +76 -0
  211. data/lib/gooddata/models/user_filters/user_filter.rb +100 -0
  212. data/lib/gooddata/models/user_filters/user_filter_builder.rb +512 -0
  213. data/lib/gooddata/models/user_filters/user_filters.rb +13 -0
  214. data/lib/gooddata/models/user_filters/variable_user_filter.rb +31 -0
  215. data/lib/gooddata/models/user_group.rb +241 -0
  216. data/lib/gooddata/rest/README.md +37 -0
  217. data/lib/gooddata/rest/client.rb +389 -0
  218. data/lib/gooddata/rest/connection.rb +765 -0
  219. data/lib/gooddata/rest/object.rb +69 -0
  220. data/lib/gooddata/rest/object_factory.rb +76 -0
  221. data/lib/gooddata/rest/resource.rb +27 -0
  222. data/lib/gooddata/rest/rest.rb +24 -0
  223. data/lib/gooddata/version.rb +23 -0
  224. data/lib/templates/bricks/brick.rb.erb +7 -0
  225. data/lib/templates/bricks/main.rb.erb +5 -0
  226. data/lib/templates/project/Goodfile.erb +4 -0
  227. data/lib/templates/project/data/commits.csv +4 -0
  228. data/lib/templates/project/data/devs.csv +4 -0
  229. data/lib/templates/project/data/repos.csv +3 -0
  230. data/lib/templates/project/model/model.rb.erb +20 -0
  231. data/spec/bricks/bricks_spec.rb +112 -0
  232. data/spec/bricks/default-config.json +8 -0
  233. data/spec/data/.gooddata +4 -0
  234. data/spec/data/blueprints/additional_dataset_module.json +32 -0
  235. data/spec/data/blueprints/big_blueprint_not_pruned.json +2079 -0
  236. data/spec/data/blueprints/invalid_blueprint.json +103 -0
  237. data/spec/data/blueprints/m_n_model.json +104 -0
  238. data/spec/data/blueprints/model_module.json +25 -0
  239. data/spec/data/blueprints/test_blueprint.json +38 -0
  240. data/spec/data/blueprints/test_project_model_spec.json +106 -0
  241. data/spec/data/cc/data/source/commits.csv +4 -0
  242. data/spec/data/cc/data/source/devs.csv +4 -0
  243. data/spec/data/cc/data/source/repos.csv +3 -0
  244. data/spec/data/cc/devel.prm +0 -0
  245. data/spec/data/cc/graph/graph.grf +11 -0
  246. data/spec/data/cc/workspace.prm +19 -0
  247. data/spec/data/column_based_permissions.csv +7 -0
  248. data/spec/data/column_based_permissions2.csv +6 -0
  249. data/spec/data/gd_gse_data_blueprint.json +1371 -0
  250. data/spec/data/gd_gse_data_manifest.json +1424 -0
  251. data/spec/data/gd_gse_data_model.json +1772 -0
  252. data/spec/data/gooddata_version_process/gooddata_version.rb +9 -0
  253. data/spec/data/gooddata_version_process/gooddata_version.zip +0 -0
  254. data/spec/data/hello_world_process/hello_world.rb +9 -0
  255. data/spec/data/hello_world_process/hello_world.zip +0 -0
  256. data/spec/data/line_based_permissions.csv +3 -0
  257. data/spec/data/manifests/test_blueprint.json +32 -0
  258. data/spec/data/manifests/test_project.json +107 -0
  259. data/spec/data/reports/left_attr_report.json +108 -0
  260. data/spec/data/reports/metric_only_one_line.json +83 -0
  261. data/spec/data/reports/report_1.json +197 -0
  262. data/spec/data/reports/top_attr_report.json +108 -0
  263. data/spec/data/ruby_params_process/ruby_params.rb +9 -0
  264. data/spec/data/ruby_process/deep_files/deep_stuff.txt +1 -0
  265. data/spec/data/ruby_process/process.rb +8 -0
  266. data/spec/data/ruby_process/stuff.txt +1 -0
  267. data/spec/data/superfluous_titles_view.json +81 -0
  268. data/spec/data/test-ci-data.csv +2 -0
  269. data/spec/data/users.csv +12 -0
  270. data/spec/data/wire_models/model_view.json +1775 -0
  271. data/spec/data/wire_models/nu_model.json +3046 -0
  272. data/spec/data/wire_models/test_blueprint.json +63 -0
  273. data/spec/data/wire_test_project.json +150 -0
  274. data/spec/environment/default.rb +41 -0
  275. data/spec/environment/develop.rb +31 -0
  276. data/spec/environment/environment.rb +18 -0
  277. data/spec/environment/hotfix.rb +21 -0
  278. data/spec/environment/production.rb +35 -0
  279. data/spec/environment/release.rb +21 -0
  280. data/spec/environment/staging.rb +30 -0
  281. data/spec/environment/staging_3.rb +36 -0
  282. data/spec/helpers/blueprint_helper.rb +26 -0
  283. data/spec/helpers/cli_helper.rb +36 -0
  284. data/spec/helpers/connection_helper.rb +41 -0
  285. data/spec/helpers/crypto_helper.rb +17 -0
  286. data/spec/helpers/csv_helper.rb +18 -0
  287. data/spec/helpers/process_helper.rb +33 -0
  288. data/spec/helpers/project_helper.rb +59 -0
  289. data/spec/helpers/schedule_helper.rb +31 -0
  290. data/spec/helpers/spec_helper.rb +15 -0
  291. data/spec/integration/blueprint_updates_spec.rb +101 -0
  292. data/spec/integration/blueprint_with_grain_spec.rb +72 -0
  293. data/spec/integration/clients_spec.rb +134 -0
  294. data/spec/integration/command_datawarehouse_spec.rb +39 -0
  295. data/spec/integration/command_projects_spec.rb +32 -0
  296. data/spec/integration/create_from_template_spec.rb +22 -0
  297. data/spec/integration/create_project_spec.rb +24 -0
  298. data/spec/integration/date_dim_switch_spec.rb +142 -0
  299. data/spec/integration/deprecated_load_spec.rb +58 -0
  300. data/spec/integration/full_process_schedule_spec.rb +298 -0
  301. data/spec/integration/full_project_spec.rb +569 -0
  302. data/spec/integration/over_to_user_filters_spec.rb +94 -0
  303. data/spec/integration/partial_md_export_import_spec.rb +42 -0
  304. data/spec/integration/project_spec.rb +264 -0
  305. data/spec/integration/rest_spec.rb +213 -0
  306. data/spec/integration/schedule_spec.rb +626 -0
  307. data/spec/integration/segments_spec.rb +141 -0
  308. data/spec/integration/user_filters_spec.rb +290 -0
  309. data/spec/integration/user_group_spec.rb +127 -0
  310. data/spec/integration/variables_spec.rb +188 -0
  311. data/spec/logging_in_logging_out_spec.rb +93 -0
  312. data/spec/spec_helper.rb +95 -0
  313. data/spec/unit/bricks/bricks_spec.rb +35 -0
  314. data/spec/unit/bricks/middleware/aws_middelware_spec.rb +51 -0
  315. data/spec/unit/bricks/middleware/bench_middleware_spec.rb +15 -0
  316. data/spec/unit/bricks/middleware/bulk_salesforce_middleware_spec.rb +15 -0
  317. data/spec/unit/bricks/middleware/gooddata_middleware_spec.rb +15 -0
  318. data/spec/unit/bricks/middleware/logger_middleware_spec.rb +15 -0
  319. data/spec/unit/bricks/middleware/restforce_middleware_spec.rb +15 -0
  320. data/spec/unit/bricks/middleware/stdout_middleware_spec.rb +15 -0
  321. data/spec/unit/bricks/middleware/twitter_middleware_spec.rb +15 -0
  322. data/spec/unit/cli/cli_spec.rb +17 -0
  323. data/spec/unit/cli/commands/cmd_auth_spec.rb +17 -0
  324. data/spec/unit/commands/command_projects_spec.rb +22 -0
  325. data/spec/unit/core/connection_spec.rb +57 -0
  326. data/spec/unit/core/logging_spec.rb +133 -0
  327. data/spec/unit/core/nil_logger_spec.rb +13 -0
  328. data/spec/unit/core/project_spec.rb +54 -0
  329. data/spec/unit/extensions/hash_spec.rb +23 -0
  330. data/spec/unit/godzilla/goodzilla_spec.rb +78 -0
  331. data/spec/unit/helpers/csv_helper_spec.rb +22 -0
  332. data/spec/unit/helpers/data_helper_spec.rb +61 -0
  333. data/spec/unit/helpers/global_helpers_spec.rb +111 -0
  334. data/spec/unit/helpers_spec.rb +86 -0
  335. data/spec/unit/models/blueprint/attributes_spec.rb +29 -0
  336. data/spec/unit/models/blueprint/dataset_spec.rb +121 -0
  337. data/spec/unit/models/blueprint/labels_spec.rb +44 -0
  338. data/spec/unit/models/blueprint/project_blueprint_spec.rb +648 -0
  339. data/spec/unit/models/blueprint/reference_spec.rb +29 -0
  340. data/spec/unit/models/blueprint/schema_builder_spec.rb +38 -0
  341. data/spec/unit/models/blueprint/to_wire_spec.rb +174 -0
  342. data/spec/unit/models/domain_spec.rb +144 -0
  343. data/spec/unit/models/execution_spec.rb +108 -0
  344. data/spec/unit/models/from_wire_spec.rb +296 -0
  345. data/spec/unit/models/invitation_spec.rb +17 -0
  346. data/spec/unit/models/membership_spec.rb +132 -0
  347. data/spec/unit/models/metadata_spec.rb +104 -0
  348. data/spec/unit/models/metric_spec.rb +117 -0
  349. data/spec/unit/models/model_spec.rb +82 -0
  350. data/spec/unit/models/params_spec.rb +118 -0
  351. data/spec/unit/models/profile_spec.rb +215 -0
  352. data/spec/unit/models/project_creator_spec.rb +127 -0
  353. data/spec/unit/models/project_role_spec.rb +94 -0
  354. data/spec/unit/models/project_spec.rb +162 -0
  355. data/spec/unit/models/report_result_data_spec.rb +199 -0
  356. data/spec/unit/models/schedule_spec.rb +418 -0
  357. data/spec/unit/models/to_manifest_spec.rb +63 -0
  358. data/spec/unit/models/unit_project_spec.rb +125 -0
  359. data/spec/unit/models/user_filters_spec.rb +95 -0
  360. data/spec/unit/models/variable_spec.rb +265 -0
  361. data/spec/unit/rest/polling_spec.rb +89 -0
  362. data/spec/unit/rest/resource_spec.rb +10 -0
  363. data/yard-server.sh +3 -0
  364. metadata +1125 -0
@@ -0,0 +1,441 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (c) 2010-2015 GoodData Corporation. All rights reserved.
4
+ # This source code is licensed under the BSD-style license found in the
5
+ # LICENSE file in the root directory of this source tree.
6
+
7
+ require 'multi_json'
8
+ require 'pmap'
9
+
10
+ require_relative 'project'
11
+ require_relative 'project_role'
12
+ require_relative 'user_group'
13
+
14
+ require_relative '../rest/object'
15
+
16
+ module GoodData
17
+ class Membership < Rest::Resource
18
+ attr_reader :json
19
+
20
+ ASSIGNABLE_MEMBERS = [
21
+ :email,
22
+ :first_name,
23
+ :last_name,
24
+ :login,
25
+ :phone,
26
+ :status,
27
+ :title
28
+ ]
29
+
30
+ class << self
31
+ # Apply changes to object.
32
+ #
33
+ # @param obj [GoodData::User] Object to be modified
34
+ # @param changes [Hash] Hash with modifications
35
+ # @return [GoodData::User] Modified object
36
+ # def apply(obj, changes)
37
+ # changes.each do |param, val|
38
+ # next unless ASSIGNABLE_MEMBERS.include? param
39
+ # obj.send("#{param}=", val)
40
+ # end
41
+ # obj
42
+ # end
43
+ def create(data, options = { client: GoodData.connection })
44
+ c = client(options)
45
+ json = {
46
+ 'user' => {
47
+ 'content' => {
48
+ 'email' => data[:email] || data[:login],
49
+ 'login' => data[:login],
50
+ 'firstname' => data[:first_name],
51
+ 'lastname' => data[:last_name],
52
+ 'userRoles' => ['editor'],
53
+ 'password' => data[:password],
54
+ 'domain' => data[:domain],
55
+ # And following lines are even much more ugly hack
56
+ # 'authentication_modes' => ['sso', 'password']
57
+ },
58
+ 'links' => {},
59
+ 'meta' => {}
60
+ }
61
+ }
62
+ json['user']['links']['self'] = data[:uri] if data[:uri]
63
+ c.create(self, json)
64
+ end
65
+
66
+ def diff_list(list_1, list_2)
67
+ GoodData::Helpers.diff(list_1, list_2, key: :login)
68
+ end
69
+ end
70
+
71
+ def initialize(json)
72
+ @json = json
73
+ end
74
+
75
+ # Checks objects for equality
76
+ #
77
+ # @param right [GoodData::User] Project to compare with
78
+ # @return [Boolean] True if same else false
79
+ def ==(other)
80
+ return false unless other.respond_to?(:to_hash)
81
+ to_hash == other.to_hash
82
+ # res = true
83
+ # ASSIGNABLE_MEMBERS.each do |k|
84
+ # l_val = send("#{k}")
85
+ # r_val = other.send("#{k}")
86
+ # res = false if l_val != r_val
87
+ # end
88
+ # res
89
+ end
90
+
91
+ # Checks objects for non-equality
92
+ #
93
+ # @param right [GoodData::User] Project to compare with
94
+ # @return [Boolean] True if different else false
95
+ def !=(other)
96
+ !(self == other)
97
+ end
98
+
99
+ # Apply changes to object.
100
+ #
101
+ # @param changes [Hash] Hash with modifications
102
+ # @return [GoodData::User] Modified object
103
+ # def apply(changes)
104
+ # GoodData::User.apply(self, changes)
105
+ # end
106
+
107
+ # Gets the contributor
108
+ #
109
+ # @return [String] Contributor
110
+ def contributor
111
+ url = @json['user']['meta']['contributor']
112
+ data = client.get url
113
+ client.create(GoodData::Membership, data)
114
+ end
115
+
116
+ # Gets date when created
117
+ #
118
+ # @return [DateTime] Created date
119
+ def created
120
+ Time.parse(@json['user']['meta']['created'])
121
+ end
122
+
123
+ # Is the member deleted?
124
+ #
125
+ # @return [Boolean] true if he is deleted
126
+ def deleted?
127
+ !(login =~ /^deleted-/).nil?
128
+ end
129
+
130
+ # Gets hash representing diff of users
131
+ #
132
+ # @param user [GoodData::User] Another profile to compare with
133
+ # @return [Hash] Hash representing diff
134
+ def diff(user)
135
+ GoodData::User.diff(self, user)
136
+ end
137
+
138
+ # Gets the email
139
+ #
140
+ # @return [String] Email address
141
+ def email
142
+ @json['user']['content']['email'] || ''
143
+ end
144
+
145
+ # Sets the email
146
+ #
147
+ # @param new_email [String] New email to be assigned
148
+ def email=(new_email)
149
+ @json['user']['content']['email'] = new_email
150
+ end
151
+
152
+ # Gets the first name
153
+ #
154
+ # @return [String] First name
155
+ def first_name
156
+ @json['user']['content']['firstname'] || ''
157
+ end
158
+
159
+ # Sets the first name
160
+ #
161
+ # @param new_first_name [String] New first name to be assigned
162
+ def first_name=(new_first_name)
163
+ @json['user']['content']['firstname'] = new_first_name
164
+ end
165
+
166
+ # Get full name
167
+ #
168
+ # @return String Full Name
169
+ # NOTE: This can be tricky to implement correctly for i18n
170
+ def full_name
171
+ "#{first_name} #{last_name}"
172
+ end
173
+
174
+ # Gets the invitations
175
+ #
176
+ # @return [Array<GoodData::Invitation>] List of invitations
177
+ def invitations
178
+ res = []
179
+
180
+ tmp = client.get @json['user']['links']['invitations']
181
+ tmp['invitations'].each do |_invitation|
182
+ # TODO: Something is missing here
183
+ end
184
+
185
+ res
186
+ end
187
+
188
+ # Gets the last name
189
+ #
190
+ # @return [String] Last name
191
+ def last_name
192
+ @json['user']['content']['lastname'] || ''
193
+ end
194
+
195
+ # Sets the last name
196
+ #
197
+ # @param new_last_name [String] New last name to be assigned
198
+ def last_name=(new_last_name)
199
+ @json['user']['content']['lastname'] = new_last_name
200
+ end
201
+
202
+ # Gets the login
203
+ #
204
+ # @return [String] Login
205
+ def login
206
+ @json['user']['content']['login'] || ''
207
+ end
208
+
209
+ # Sets the last name
210
+ #
211
+ # @param new_login [String] New login to be assigned
212
+ def login=(new_login)
213
+ @json['user']['content']['login'] = new_login
214
+ end
215
+
216
+ # Gets user raw object ID
217
+ #
218
+ # @return [String] Raw Object ID
219
+ def obj_id
220
+ uri.split('/').last
221
+ end
222
+
223
+ # Gets the permissions
224
+ #
225
+ # @return [Hash] Hash with permissions
226
+ def permissions
227
+ res = {}
228
+
229
+ tmp = client.get @json['user']['links']['permissions']
230
+ tmp['associatedPermissions']['permissions'].each do |permission_name, permission_value|
231
+ res[permission_name] = permission_value
232
+ end
233
+
234
+ res
235
+ end
236
+
237
+ # Gets the phone number
238
+ #
239
+ # @return [String] Phone number
240
+ def phone
241
+ @json['user']['content']['phonenumber'] || ''
242
+ end
243
+
244
+ # Sets the phone number
245
+ #
246
+ # @param new_phone_number [String] New phone number to be assigned
247
+ def phone=(new_phone_number)
248
+ @json['user']['content']['phonenumber'] = new_phone_number
249
+ end
250
+
251
+ # Gets profile of this membership
252
+ def profile
253
+ raw = client.get @json['user']['links']['self']
254
+ client.create(GoodData::Profile, raw)
255
+ end
256
+
257
+ # Gets URL of profile membership
258
+ def profile_url
259
+ @json['user']['links']['self']
260
+ end
261
+
262
+ # # Gets project which this membership relates to
263
+ # def project
264
+ # raw = client.get project_url
265
+ # client.create(GoodData::Project, raw)
266
+ # end
267
+
268
+ # Gets project id
269
+ def project_id
270
+ @json['user']['links']['roles'].split('/')[3]
271
+ end
272
+
273
+ # Gets project url
274
+ def project_url
275
+ @json['user']['links']['roles'].split('/')[0..3].join('/')
276
+ end
277
+
278
+ # Gets the projects of user
279
+ #
280
+ # @return [Array<GoodData::Project>] Array of projets
281
+ def projects
282
+ tmp = client.get @json['user']['links']['projects']
283
+ tmp['projects'].map do |project_meta|
284
+ project_uri = project_meta['project']['links']['self']
285
+ project = client.get project_uri
286
+ client.create(GoodData::Project, project)
287
+ end
288
+ end
289
+
290
+ # Gets first role
291
+ #
292
+ # @return [GoodData::ProjectRole] Array of project roles
293
+ def role
294
+ roles && roles.first
295
+ end
296
+
297
+ # Gets the project roles of user
298
+ #
299
+ # @return [Array<GoodData::ProjectRole>] Array of project roles
300
+ def roles
301
+ # TODO: Implement getting roles in project and cache them there
302
+ # See: https://jira.intgdc.com/browse/TMA-112
303
+ roles_link = GoodData::Helpers.get_path(@json, %w(user links roles))
304
+ return unless roles_link
305
+ tmp = client.get roles_link
306
+ tmp['associatedRoles']['roles'].pmap do |role_uri|
307
+ role = client.get role_uri
308
+ client.create(GoodData::ProjectRole, role)
309
+ end
310
+ end
311
+
312
+ # Gets the status
313
+ #
314
+ # @return [String] Status
315
+ def status
316
+ @json['user']['content']['status'] || ''
317
+ end
318
+
319
+ # Gets the title
320
+ #
321
+ # @return [String] User title
322
+ def title
323
+ @json['user']['meta']['title'] || ''
324
+ end
325
+
326
+ # Sets the title
327
+ #
328
+ # @param new_title [String] New title to be assigned
329
+ def title=(new_title)
330
+ @json['user']['content']['title'] = new_title
331
+ end
332
+
333
+ # Gets the date when updated
334
+ #
335
+ # @return [DateTime] Date of last update
336
+ def updated
337
+ DateTime.parse(@json['user']['meta']['updated'])
338
+ end
339
+
340
+ # Gets the object URI
341
+ #
342
+ # @return [String] Object URI
343
+ def uri
344
+ links['self']
345
+ end
346
+
347
+ # Enables membership
348
+ #
349
+ # @return [GoodData::Membership] returns self
350
+ def enable
351
+ self.status = 'ENABLED'
352
+ self
353
+ end
354
+
355
+ # Is the member enabled?
356
+ #
357
+ # @return [Boolean] true if it is enabled
358
+ def enabled?
359
+ status == 'ENABLED'
360
+ end
361
+
362
+ # Disables membership
363
+ #
364
+ # @return [GoodData::Membership] returns self
365
+ def disable
366
+ self.status = 'DISABLED'
367
+ self
368
+ end
369
+
370
+ # Is the member enabled?
371
+ #
372
+ # @return [Boolean] true if it is disabled
373
+ def disabled?
374
+ !enabled?
375
+ end
376
+
377
+ def data
378
+ data = @json || {}
379
+ data['user'] || {}
380
+ end
381
+
382
+ def name
383
+ (first_name || '') + (last_name || '')
384
+ end
385
+
386
+ def meta
387
+ data['meta'] || {}
388
+ end
389
+
390
+ def links
391
+ data['links'] || {}
392
+ end
393
+
394
+ def content
395
+ data['content'] || {}
396
+ end
397
+
398
+ def to_hash
399
+ tmp = GoodData::Helpers.symbolize_keys(content.merge(meta).merge('uri' => uri))
400
+ [
401
+ [:userRoles, :role],
402
+ [:companyName, :company_name],
403
+ [:phoneNumber, :phone_number],
404
+ [:firstname, :first_name],
405
+ [:lastname, :last_name],
406
+ [:authenticationModes, :authentication_modes]
407
+ ].each do |vals|
408
+ wire, rb = vals
409
+ tmp[rb] = tmp[wire]
410
+ tmp.delete(wire)
411
+ end
412
+ tmp
413
+ end
414
+
415
+ def user_groups
416
+ project.user_groups(:all, user: obj_id)
417
+ end
418
+
419
+ private
420
+
421
+ # Sets status to 'ENABLED' or 'DISABLED'
422
+ def status=(new_status)
423
+ payload = {
424
+ 'user' => {
425
+ 'content' => {
426
+ 'status' => new_status.to_s.upcase,
427
+ 'userRoles' => @json['user']['content']['userRoles']
428
+ },
429
+ 'links' => {
430
+ 'self' => uri
431
+ }
432
+ }
433
+ }
434
+
435
+ res = client.post("/gdc/projects/#{project_id}/users", payload)
436
+ fail 'Update failed' unless res['projectUsersUpdateResult']['failed'].empty?
437
+ @json['user']['content']['status'] = new_status.to_s.upcase
438
+ self
439
+ end
440
+ end
441
+ end
@@ -0,0 +1,272 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright (c) 2010-2015 GoodData Corporation. All rights reserved.
4
+ # This source code is licensed under the BSD-style license found in the
5
+ # LICENSE file in the root directory of this source tree.
6
+
7
+ require 'multi_json'
8
+
9
+ require_relative '../core/project'
10
+
11
+ require_relative '../mixins/mixins'
12
+ require_relative '../rest/object'
13
+
14
+ module GoodData
15
+ class MdObject < Rest::Resource
16
+ MD_OBJ_CTG = 'obj'
17
+ IDENTIFIERS_CFG = 'instance-identifiers'
18
+
19
+ extend Mixin::MdIdToUri
20
+ extend Mixin::MdObjectIndexer
21
+ extend Mixin::MdObjectQuery
22
+
23
+ extend Mixin::MdFinders
24
+ extend Mixin::MdObjId
25
+
26
+ include Mixin::Links
27
+ include Mixin::ObjId
28
+ include Mixin::MdRelations
29
+ include Mixin::MdGrantees
30
+
31
+ class << self
32
+ # Method used for replacing objects like Attribute, Fact or Metric. It takes the object. Scans its JSON
33
+ # representation and returns a new one with object references changed according to mapping. The references an be found either in the object structure or in the MAQL in bracketed form. This implementation takes care only of those in bracketed form.
34
+ #
35
+ # @param obj [GoodData::MdObject] what Object that should be replaced
36
+ # @param mapping [Array[Array]] Array of mapping pairs.
37
+ # @return [GoodData::MdObject]
38
+ def replace_bracketed(obj, mapping)
39
+ replace(obj, mapping) { |e, a, b| e.gsub("[#{a}]", "[#{b}]") }
40
+ end
41
+
42
+ # Method used for replacing objects like Attribute, Fact or Metric. It takes the object. Scans its JSON
43
+ # representation and returns a new one with object references changed according to mapping. The references an be found either in the object structure or in the MAQL in bracketed form. This implementation takes care only of those in object structure where they are as a string in JSON.
44
+ #
45
+ # @param obj [GoodData::MdObject] Object that should be replaced
46
+ # @param mapping [Array[Array]] Array of mapping pairs.
47
+ # @return [GoodData::MdObject]
48
+ def replace_quoted(obj, mapping)
49
+ replace(obj, mapping) do |e, a, b|
50
+ e.gsub("\"#{a}\"", "\"#{b}\"")
51
+ end
52
+ end
53
+
54
+ # Helper method used for replacing objects like Attribute, Fact or Metric. It takes the object. Scans its JSON
55
+ # representation yields for a client to perform replacement for each mapping pair and returns a new one
56
+ # with object of the same type as obj.
57
+ #
58
+ # @param obj [GoodData::MdObject] Object that should be replaced
59
+ # @param mapping [Array[Array]] Array of mapping pairs.
60
+ # @param block [Proc] Block that receives the object state as a JSON string and mapping pair and expects a new object state as a JSON string back
61
+ # @return [GoodData::MdObject]
62
+ def replace(obj, mapping, &block)
63
+ json = mapping.reduce(obj.to_json) do |a, e|
64
+ obj_a, obj_b = e
65
+ uri_what = obj_a.respond_to?(:uri) ? obj_a.uri : obj_a
66
+ uri_for_what = obj_b.respond_to?(:uri) ? obj_b.uri : obj_b
67
+ block.call(a, uri_what, uri_for_what)
68
+ end
69
+ client = obj.client
70
+ client.create(obj.class, MultiJson.load(json), :project => obj.project)
71
+ end
72
+
73
+ # Helper method used for finding attribute elements that are interesting becuase they can be possibly
74
+ # replaced according to mapping specification. This walks through all the attribute elemets. Picks only those
75
+ # whose attribute is mentioned in the mapping. Walks through all the labels of that particular attribute and
76
+ # tries to find a value from one to be translated into a label in second. Obviously this is not guaranteed to
77
+ # find any results or in some cases can yield to incorrect results.
78
+ #
79
+ # @param obj [GoodData::MdObject] Object that should be replaced
80
+ # @param mapping [Array[Array]] Array of mapping pairs.
81
+ # @param block [Proc] Block that receives the object state as a JSON string and mapping pair and expects a new object state as a JSON string back
82
+ # @return [GoodData::MdObject]
83
+ def find_replaceable_values(obj, mapping)
84
+ values_to_replace = GoodData::SmallGoodZilla.extract_element_uri_pairs(MultiJson.dump(obj.to_json))
85
+ values_from_mapping = values_to_replace.select { |i| mapping.map { |a, _| a.uri }.include?(i.first) }
86
+ replaceable_vals = values_from_mapping.map do |a_uri, id|
87
+ from_attribute, to_attribute = mapping.find { |k, _| k.uri == a_uri }
88
+ vals = from_attribute.values_for(id)
89
+ labels = to_attribute.labels
90
+ results = labels.to_enum.mapcat do |l|
91
+ vals.map do |v|
92
+ begin
93
+ l.find_value_uri(v)
94
+ rescue
95
+ nil
96
+ end
97
+ end
98
+ end
99
+ fail "Unable to find replacement for #{a_uri}" if results.compact.empty?
100
+ [a_uri, id, results.compact.first]
101
+ end
102
+ replaceable_vals.map { |a, id, r| ["#{a}/elements?id=#{id}", r] }
103
+ end
104
+ end
105
+
106
+ metadata_property_reader :uri, :identifier, :title, :summary, :tags, :category
107
+ metadata_property_writer :tags, :summary, :title, :identifier
108
+
109
+ def initialize(data)
110
+ @json = data.to_hash
111
+ end
112
+
113
+ def add_tag(a_tag)
114
+ self.tags = tag_set.add(a_tag).to_a.join(' ')
115
+ self
116
+ end
117
+
118
+ def delete
119
+ if saved? # rubocop:disable Style/GuardClause
120
+ client.delete(uri)
121
+ meta.delete('uri')
122
+ end
123
+ end
124
+
125
+ def reload!
126
+ @json = client.get(uri) if saved?
127
+ self
128
+ end
129
+
130
+ alias_method :refresh, :reload!
131
+
132
+ def browser_uri
133
+ client.connection.server_url + meta['uri']
134
+ end
135
+
136
+ def deprecated
137
+ if meta['deprecated'] == '1'
138
+ true
139
+ else
140
+ false
141
+ end
142
+ end
143
+ alias_method :deprecated?, :deprecated
144
+
145
+ def deprecated=(flag)
146
+ if flag == '1' || flag == 1 || flag == true
147
+ meta['deprecated'] = '1'
148
+ elsif flag == '0' || flag == 0 || flag == false
149
+ meta['deprecated'] = '0'
150
+ else
151
+ fail 'You have to provide flag as either 1 or "1" or 0 or "0" or true/false'
152
+ end
153
+ end
154
+
155
+ def project
156
+ @project ||= Project[uri.gsub(%r{\/obj\/\d+$}, ''), :client => client]
157
+ end
158
+
159
+ # Method used for replacing objects like Attribute, Fact or Metric. Returns new object of the same type.
160
+ #
161
+ # @param [GoodData::MdObject] what Object that should be replaced
162
+ # @param [GoodData::MdObject] for_what Object it is replaced with
163
+ # @return [GoodData::Metric]
164
+ def replace(mapping)
165
+ GoodData::MdObject.replace_quoted(self, mapping)
166
+ end
167
+
168
+ # Method used for replacing objects like Attribute, Fact or Metric. Returns itself mutated.
169
+ # @param [GoodData::MdObject] what Object that should be replaced
170
+ # @param [GoodData::MdObject] for_what Object it is replaced with
171
+ # @return [GoodData::Metric]
172
+ def replace!(mapping)
173
+ x = replace(mapping)
174
+ @json = x.json
175
+ self
176
+ end
177
+
178
+ def remove_tag(a_tag)
179
+ self.tags = tag_set.delete(a_tag).to_a.join(' ')
180
+ self
181
+ end
182
+
183
+ def save
184
+ fail('Validation failed') unless validate
185
+
186
+ opts = {
187
+ :client => client,
188
+ :project => project
189
+ }
190
+
191
+ if saved?
192
+ client.put(uri, to_json)
193
+ else
194
+ explicit_identifier = meta['identifier']
195
+ # Pre-check to provide a user-friendly error rather than
196
+ # failing later
197
+ klass = self.class
198
+ if explicit_identifier && klass[explicit_identifier, opts]
199
+ fail "Identifier '#{explicit_identifier}' already in use"
200
+ end
201
+
202
+ req_uri = project.md['obj']
203
+ result = client.post(req_uri, to_json)
204
+ saved_object = self.class[result['uri'], opts]
205
+ # TODO: add test for explicitly provided identifier
206
+
207
+ @json = saved_object.json
208
+ if explicit_identifier
209
+ # Object creation API discards the identifier. If an identifier
210
+ # was explicitely provided in the origina object, we need to set
211
+ # it explicitly with an extra PUT call.
212
+ meta['identifier'] = explicit_identifier
213
+ begin
214
+ client.put(uri, to_json)
215
+ rescue => e
216
+ # Cannot change the identifier (perhaps because it's in use
217
+ # already?), cleaning up.
218
+ client.delete(uri)
219
+ raise e
220
+ end
221
+ end
222
+ end
223
+ self
224
+ end
225
+
226
+ # Saves an object with a different name
227
+ #
228
+ # @param new_title [String] New title. If not provided one is provided
229
+ # @return [GoodData::MdObject] MdObject that has been saved as
230
+ def save_as(new_title = nil)
231
+ new_title = "Clone of #{title}" if new_title.nil?
232
+
233
+ dupped = Marshal.load(Marshal.dump(json))
234
+ dupped[root_key]['meta'].delete('uri')
235
+ dupped[root_key]['meta'].delete('identifier')
236
+ dupped[root_key]['meta']['title'] = new_title
237
+ x = client.create(self.class, dupped, :project => project)
238
+ x.save
239
+ end
240
+
241
+ def tag_set
242
+ tags.scan(/\w+/).to_set
243
+ end
244
+
245
+ def ==(other)
246
+ other.respond_to?(:uri) && other.uri == uri && other.respond_to?(:to_hash) && other.to_hash == to_hash
247
+ end
248
+
249
+ def listed?
250
+ !unlisted?
251
+ end
252
+
253
+ def unlisted
254
+ meta['unlisted'] == '1'
255
+ end
256
+ alias_method :unlisted?, :unlisted
257
+
258
+ def unlisted=(flag)
259
+ if flag == true
260
+ meta['unlisted'] = '1'
261
+ elsif flag == false
262
+ meta['unlisted'] = '0'
263
+ else
264
+ fail 'You have to provide flag as either true or false'
265
+ end
266
+ end
267
+
268
+ def validate
269
+ true
270
+ end
271
+ end
272
+ end