gooddata-edge 0.6.27.edge

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,479 @@
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 'cgi'
8
+
9
+ require_relative 'profile'
10
+ require_relative '../extensions/enumerable'
11
+ require_relative '../rest/object'
12
+
13
+ module GoodData
14
+ class Domain < Rest::Resource
15
+ attr_reader :name
16
+
17
+ ProvisioningResult = Struct.new('ProvisioningResult', :id, :status, :project_uri, :error)
18
+
19
+ class << self
20
+ # Looks for domain
21
+ #
22
+ # @param domain_name [String] Domain name
23
+ # @return [String] Domain object instance
24
+ def [](domain_name, options = { :client => GoodData.connection })
25
+ return domain_name if domain_name.is_a?(Domain)
26
+ c = client(options)
27
+ fail "Using pseudo-id 'all' is not supported by GoodData::Domain" if domain_name.to_s == 'all'
28
+ c.create(GoodData::Domain, domain_name)
29
+ end
30
+
31
+ # Adds user to domain
32
+ #
33
+ # @param domain [String] Domain name
34
+ # @param login [String] Login of user to be invited
35
+ # @param password [String] Default preset password
36
+ # @return [Object] Raw response
37
+ def add_user(user_data, name = nil, opts = { :client => GoodData.connection })
38
+ generated_pass = rand(10E10).to_s
39
+ domain_name = name || user_data[:domain]
40
+ user_data = user_data.to_hash
41
+ data = {
42
+ :login => user_data[:login] || user_data[:email],
43
+ :firstName => user_data[:first_name] || 'FirstName',
44
+ :lastName => user_data[:last_name] || 'LastName',
45
+ :password => user_data[:password] || generated_pass,
46
+ :verifyPassword => user_data[:password] || generated_pass,
47
+ :email => user_data[:email] || user_data[:login]
48
+ }
49
+
50
+ # Optional authentication modes
51
+ tmp = user_data[:authentication_modes]
52
+ if tmp
53
+ if tmp.is_a? Array
54
+ data[:authenticationModes] = tmp
55
+ elsif tmp.is_a? String
56
+ data[:authenticationModes] = [tmp]
57
+ end
58
+ end
59
+
60
+ # Optional company
61
+ tmp = user_data[:company_name]
62
+ tmp = user_data[:company] if tmp.nil? || tmp.empty?
63
+ data[:companyName] = tmp if tmp && !tmp.empty?
64
+
65
+ # Optional country
66
+ tmp = user_data[:country]
67
+ data[:country] = tmp if tmp && !tmp.empty?
68
+
69
+ # Optional phone number
70
+ tmp = user_data[:phone]
71
+ tmp = user_data[:phone_number] if tmp.nil? || tmp.empty?
72
+ data[:phoneNumber] = tmp if tmp && !tmp.empty?
73
+
74
+ # Optional position
75
+ tmp = user_data[:position]
76
+ data[:position] = tmp if tmp && !tmp.empty?
77
+
78
+ # Optional sso provider
79
+ tmp = user_data[:sso_provider]
80
+ data['ssoProvider'] = tmp if tmp && !tmp.empty?
81
+
82
+ # Optional timezone
83
+ tmp = user_data[:timezone]
84
+ data[:timezone] = tmp if tmp && !tmp.empty?
85
+
86
+ c = client(opts)
87
+
88
+ # TODO: It will be nice if the API will return us user just newly created
89
+ begin
90
+ url = "/gdc/account/domains/#{domain_name}/users"
91
+ response = c.post(url, :accountSetting => data)
92
+ rescue RestClient::BadRequest => e
93
+ error = MultiJson.load(e.response)
94
+ error_type = GoodData::Helpers.get_path(error, %w(error errorClass))
95
+ case error_type
96
+ when 'com.gooddata.webapp.service.userprovisioning.LoginNameAlreadyRegisteredException'
97
+ raise GoodData::UserInDifferentDomainError, "User #{data[:login]} is already in different domain"
98
+ when 'com.gooddata.json.validator.exception.MalformedMessageException'
99
+ raise GoodData::MalformedUserError, "User #{data[:login]} is malformed. The message from API is #{GoodData::Helpers.interpolate_error_message(error)}"
100
+ else
101
+ raise GoodData::Helpers.interpolate_error_message(error)
102
+ end
103
+ end
104
+
105
+ url = response['uri']
106
+ raw = c.get url
107
+
108
+ # TODO: Remove this hack when POST /gdc/account/domains/{domain-name}/users returns full profile
109
+ raw['accountSetting']['links'] = {} unless raw['accountSetting']['links']
110
+ raw['accountSetting']['links']['self'] = response['uri'] unless raw['accountSetting']['links']['self']
111
+ c.create(GoodData::Profile, raw)
112
+ end
113
+
114
+ def update_user(user_data, options = { client: GoodData.connection })
115
+ user_data = user_data.to_hash if user_data.is_a?(GoodData::Profile)
116
+ client = client(options)
117
+ user_data = user_data.to_hash
118
+ # generated_pass = rand(10E10).to_s
119
+ data = {
120
+ :firstName => user_data[:first_name] || 'FirstName',
121
+ :lastName => user_data[:last_name] || 'LastName',
122
+ :email => user_data[:email]
123
+ }
124
+
125
+ # Optional authentication modes
126
+ tmp = user_data[:authentication_modes]
127
+ if tmp
128
+ if tmp.is_a? Array
129
+ data[:authenticationModes] = tmp
130
+ elsif tmp.is_a? String
131
+ data[:authenticationModes] = [tmp]
132
+ end
133
+ end
134
+
135
+ # Optional company
136
+ tmp = user_data[:company_name]
137
+ tmp = user_data[:company] if tmp.nil? || tmp.empty?
138
+ data[:companyName] = tmp if tmp && !tmp.empty?
139
+
140
+ # Optional pass
141
+ tmp = user_data[:password]
142
+ tmp = user_data[:password] if tmp.nil? || tmp.empty?
143
+ data[:password] = tmp if tmp && !tmp.empty?
144
+ data[:verifyPassword] = tmp if tmp && !tmp.empty?
145
+
146
+ # Optional country
147
+ tmp = user_data[:country]
148
+ data[:country] = tmp if tmp && !tmp.empty?
149
+
150
+ # Optional phone number
151
+ tmp = user_data[:phone]
152
+ tmp = user_data[:phone_number] if tmp.nil? || tmp.empty?
153
+ data[:phoneNumber] = tmp if tmp && !tmp.empty?
154
+
155
+ # Optional position
156
+ tmp = user_data[:position]
157
+ data[:position] = tmp if tmp && !tmp.empty?
158
+
159
+ # Optional sso provider
160
+ tmp = user_data[:sso_provider]
161
+ data['ssoProvider'] = tmp if tmp
162
+
163
+ # Optional timezone
164
+ tmp = user_data[:timezone]
165
+ data[:timezone] = tmp if tmp && !tmp.empty?
166
+
167
+ # TODO: It will be nice if the API will return us user just newly created
168
+ url = user_data.delete(:uri)
169
+ data.delete(:password) if client.user.uri == url
170
+ response = client.put(url, :accountSetting => data)
171
+
172
+ # TODO: Remove this hack when POST /gdc/account/domains/{domain-name}/users returns full profile
173
+ response['accountSetting']['links'] = {} unless response['accountSetting']['links']
174
+ response['accountSetting']['links']['self'] = url unless response['accountSetting']['links']['self']
175
+ client.create(GoodData::Profile, response)
176
+ end
177
+
178
+ # Finds user in domain by login
179
+ #
180
+ # @param domain [String] Domain name
181
+ # @param login [String] User login
182
+ # @return [GoodData::Profile] User profile
183
+ def find_user_by_login(domain, login, opts = { :client => GoodData.connection, :project => GoodData.project })
184
+ c = client(opts)
185
+ escaped_login = CGI.escape(login)
186
+ domain = c.domain(domain)
187
+ GoodData.logger.warn("Retrieving particular user \"#{login.inspect}\" from domain #{domain.name}")
188
+ url = "#{domain.uri}/users?login=#{escaped_login}"
189
+ tmp = c.get url
190
+ items = tmp['accountSettings']['items'] if tmp['accountSettings']
191
+ items && !items.empty? ? c.factory.create(GoodData::Profile, items.first) : nil
192
+ end
193
+
194
+ # Returns list of users for domain specified
195
+ # @param [String] domain Domain to list the users for
196
+ # @param [Hash] opts Options.
197
+ # @option opts [Number] :offset The subject
198
+ # @option opts [Number] :limit From address
199
+ # TODO: Review opts[:limit] functionality
200
+ def users(domain, id = :all, opts = {})
201
+ client = client(opts)
202
+ domain = client.domain(domain)
203
+ if id == :all
204
+ GoodData.logger.warn("Retrieving all users from domain #{domain.name}")
205
+ Enumerator.new do |y|
206
+ page_limit = opts[:page_limit] || 1000
207
+ offset = opts[:offset] || 0
208
+ loop do
209
+ begin
210
+ tmp = client(opts).get("#{domain.uri}/users", params: { offset: offset, limit: page_limit })
211
+ end
212
+
213
+ tmp['accountSettings']['items'].each do |user_data|
214
+ user = client.create(GoodData::Profile, user_data)
215
+ y << user if user
216
+ end
217
+ break if tmp['accountSettings']['items'].count < page_limit
218
+ offset += page_limit
219
+ end
220
+ end
221
+ else
222
+ find_user_by_login(domain, id)
223
+ end
224
+ end
225
+
226
+ # Create users specified in list
227
+ # @param [Array<GoodData::Membership>] list List of users
228
+ # @param [String] default_domain_name Default domain name used when no specified in user
229
+ # @return [Array<GoodData::User>] List of users created
230
+ def create_users(list, default_domain = nil, opts = { :client => GoodData.connection, :project => GoodData.project })
231
+ default_domain_name = default_domain.respond_to?(:name) ? default_domain.name : default_domain
232
+ domain = client.domain(default_domain_name)
233
+
234
+ # Prepare cache for domain users
235
+ domain_users_cache = Hash[domain.users.map { |u| [u.login, u] }]
236
+
237
+ list.pmapcat do |user|
238
+ begin
239
+ user_data = user.to_hash
240
+ domain_user = domain_users_cache[user_data[:login]]
241
+ if !domain_user
242
+ added_user = domain.add_user(user_data, opts)
243
+ [{ type: :successful, :action => :user_added_to_domain, user: added_user }]
244
+ else
245
+ fields_to_check = opts[:fields_to_check] || user_data.keys
246
+ diff = GoodData::Helpers.diff([domain_user.to_hash], [user_data], key: :login, fields: fields_to_check)
247
+ next [] if diff[:changed].empty?
248
+ updated_user = domain.update_user(domain_user.to_hash.merge(user_data.compact), opts)
249
+ [{ type: :successful, :action => :user_changed_in_domain, user: updated_user }]
250
+ end
251
+ rescue RuntimeError => e
252
+ [{ type: :failed, :user => user, message: e }]
253
+ end
254
+ end
255
+ end
256
+ end
257
+
258
+ def initialize(domain_name)
259
+ @name = domain_name
260
+ end
261
+
262
+ # Adds user to domain
263
+ #
264
+ # @param login [String] Login of user to be invited
265
+ # @param password [String] Default preset password
266
+ # @return [Object] Raw response
267
+ #
268
+ # Example
269
+ #
270
+ # GoodData.connect 'tomas.korcak@gooddata.com' 'your-password'
271
+ # domain = project.domain('domain-name')
272
+ # domain.add_user 'joe.doe@example', 'sup3rS3cr3tP4ssW0rtH'
273
+ #
274
+ def add_user(data, opts = {})
275
+ # data[:domain] = name
276
+ GoodData::Domain.add_user(data, name, { client: client }.merge(opts))
277
+ end
278
+
279
+ # Returns all the clients defined in all segments defined in domain. Alternatively
280
+ # id of a client can be provided in which case it returns just that client
281
+ # if it exists.
282
+ #
283
+ # @param id [String] Id of client that you are looking for
284
+ # @return [Object] Raw response
285
+ #
286
+ def clients(id = :all)
287
+ clients_uri = "/gdc/domains/#{name}/clients"
288
+ res = client.get(clients_uri)
289
+ res_clients = (res['clients'] && res['clients']['items']) || []
290
+ if id == :all
291
+ res_clients.map { |res_client| client.create(GoodData::Client, res_client) }
292
+ else
293
+ find_result = res_clients.find { |c| c['client']['id'] == id }
294
+ fail "Client with id #{id} was not found" unless find_result
295
+ client.create(GoodData::Client, find_result)
296
+ end
297
+ end
298
+
299
+ alias_method :create_user, :add_user
300
+
301
+ def create_users(list, options = {})
302
+ GoodData::Domain.create_users(list, name, { client: client }.merge(options))
303
+ end
304
+
305
+ def segments(id = :all)
306
+ GoodData::Segment[id, domain: self]
307
+ end
308
+
309
+ # Creates new segment in current domain from parameters passed
310
+ #
311
+ # @param data [Hash] Data for segment namely :segment_id and :master_project is accepted. Master_project can be given as either a PID or a Project instance
312
+ # @return [GoodData::Segment] New Segment instance
313
+ def create_segment(data)
314
+ segment = GoodData::Segment.create(data, domain: self, client: client)
315
+ segment.save
316
+ end
317
+
318
+ # Gets user by its login or uri in various shapes
319
+ # It does not find by other information because that is not unique. If you want to search by name or email please
320
+ # use fuzzy_get_user.
321
+ #
322
+ # @param [String] name Name to look for
323
+ # @param [Array<GoodData::User>]user_list Optional cached list of users used for look-ups
324
+ # @return [GoodDta::Membership] User
325
+ def get_user(name, user_list = users)
326
+ return member(name, user_list) if name.instance_of?(GoodData::Membership)
327
+ return member(name, user_list) if name.instance_of?(GoodData::Profile)
328
+ name = name.is_a?(Hash) ? name[:login] || name[:uri] : name
329
+ return nil unless name
330
+ name.downcase!
331
+ user_list.find do |user|
332
+ user.uri && user.uri.downcase == name ||
333
+ user.login && user.login.downcase == name
334
+ end
335
+ end
336
+
337
+ # Finds user in domain by login
338
+ #
339
+ # @param login [String] User login
340
+ # @return [GoodData::Profile] User account settings
341
+ def find_user_by_login(login)
342
+ GoodData::Domain.find_user_by_login(self, login, client: client)
343
+ end
344
+
345
+ # Gets membership for profile specified
346
+ #
347
+ # @param [GoodData::Profile] profile - Profile to be checked
348
+ # @param [Array<GoodData::Profile>] list Optional list of members to check against
349
+ # @return [GoodData::Profile] Profile if found
350
+ def member(profile, list = members)
351
+ if profile.is_a? String
352
+ return list.find do |m|
353
+ m.uri == profile || m.login == profile
354
+ end
355
+ end
356
+ list.find { |m| m.login == profile.login }
357
+ end
358
+
359
+ # Checks if the profile is member of project
360
+ #
361
+ # @param [GoodData::Profile] profile - Profile to be checked
362
+ # @param [Array<GoodData::Membership>] list Optional list of members to check against
363
+ # @return [Boolean] true if is member else false
364
+ def member?(profile, list = members)
365
+ !member(profile, list).nil?
366
+ end
367
+
368
+ def members?(profiles, list = members)
369
+ profiles.map { |p| member?(p, list) }
370
+ end
371
+
372
+ # Returns uri for segments on the domain. This will be removed soon. It is here that for segments the "account" portion of the URI was removed. And not for the rest
373
+ #
374
+ # @return [String] Uri of the segments
375
+ def segments_uri
376
+ "/gdc/domains/#{name}"
377
+ end
378
+
379
+ # Calls Segment#synchronize_clients on all segments and concatenates the results
380
+ #
381
+ # @return [Array] Returns array of results
382
+ def synchronize_clients
383
+ segments.flat_map(&:synchronize_clients)
384
+ end
385
+
386
+ # Runs async process that walks through segments and provisions projects if necessary.
387
+ #
388
+ # @return [Enumerator] Returns Enumerator of results
389
+ def provision_client_projects
390
+ res = client.post(segments_uri + '/provisionClientProjects', nil)
391
+ res = client.poll_on_code(res['asyncTask']['links']['poll'])
392
+ failed_count = GoodData::Helpers.get_path(res, %w(clientProjectProvisioningResult failed count), 0)
393
+ created_count = GoodData::Helpers.get_path(res, %w(clientProjectProvisioningResult created count), 0)
394
+ return Enumerator.new([]) if failed_count + created_count == 0
395
+ Enumerator.new do |y|
396
+ uri = GoodData::Helpers.get_path(res, %w(clientProjectProvisioningResult links details))
397
+ loop do
398
+ result = client.get(uri)
399
+ (GoodData::Helpers.get_path(result, %w(clientProjectProvisioningResultDetails items)) || []).each do |item|
400
+ y << ProvisioningResult.new(item['id'], item['status'], item['project'], item['error'])
401
+ end
402
+ uri = GoodData::Helpers.get_path(res, %w(clientProjectProvisioningResultDetails paging next))
403
+ break if uri.nil?
404
+ end
405
+ end
406
+ end
407
+
408
+ def update_clients(data, options = {})
409
+ delete_projects = options[:delete_projects] == false ? false : true
410
+ payload = data.map do |datum|
411
+ {
412
+ :client => {
413
+ :id => datum[:id],
414
+ :segment => segments_uri + '/segments/' + datum[:segment]
415
+ }
416
+ }.tap do |h|
417
+ h[:client][:project] = datum[:project] if datum.key?(:project)
418
+ end
419
+ end
420
+ if options[:delete_extra] == true
421
+ res = client.post(segments_uri + '/updateClients?deleteExtra=true', updateClients: { items: payload })
422
+ else
423
+ res = client.post(segments_uri + '/updateClients', updateClients: { items: payload })
424
+ end
425
+ data = GoodData::Helpers.get_path(res, ['updateClientsResponse'])
426
+ if data
427
+ result = data.flat_map { |k, v| v.map { |h| GoodData::Helpers.symbolize_keys(h.merge('type' => k)) } }
428
+ result.select { |r| r[:status] == 'DELETED' }.peach { |r| r[:originalProject] && client.delete(r[:originalProject]) } if delete_projects
429
+ result
430
+ else
431
+ []
432
+ end
433
+ end
434
+
435
+ # Update user in domain
436
+ #
437
+ # @param opts [Hash] Data of the user to be updated
438
+ # @return [Object] Raw response
439
+ #
440
+ def update_user(data, options = {})
441
+ GoodData::Domain.update_user(data, { client: client }.merge(options))
442
+ end
443
+
444
+ # List users in domain
445
+ #
446
+ # @param [Hash] opts Additional user listing options.
447
+ # @option opts [Number] :offset Offset to start listing from
448
+ # @option opts [Number] :limit Limit of users to be listed
449
+ # @return [Array<GoodData::Profile>] List of user account settings
450
+ #
451
+ # Example
452
+ #
453
+ # GoodData.connect 'tomas.korcak@gooddata.com' 'your-password'
454
+ # domain = GoodData::Domain['gooddata-tomas-korcak']
455
+ # pp domain.users
456
+ #
457
+ def users(id = :all, opts = {})
458
+ GoodData::Domain.users(name, id, opts.merge(client: client))
459
+ end
460
+
461
+ alias_method :members, :users
462
+
463
+ # Returns uri for the domain.
464
+ #
465
+ # @return [String] Uri of the segments
466
+ def uri
467
+ "/gdc/account/domains/#{name}"
468
+ end
469
+
470
+ private
471
+
472
+ # Private setter of domain name. Used by constructor not available for external users.
473
+ #
474
+ # @param domain_name [String] Domain name to be set.
475
+ def name=(domain_name) # rubocop:disable TrivialAccessors
476
+ @name = domain_name
477
+ end
478
+ end
479
+ end